#ifndef __LOW_POWER_H__
#define __LOW_POWER_H__
#include "stm32l4xx_hal.h"
#include "DELAY.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

/*
进入低功耗的函数中 每个模式都有一个10ms的消抖 其实这个可以省略
但我们用的是HAL库 HAL库初始化时钟以后 会打开SysTick中断 如果这个开着 就一直无法进入低功耗（进入就被中断唤醒）
所以我这里加了个我自己写的延时函数 其中就有关闭SysTick的语句
如果你不用这个消抖 没啥BUG也行 但我还是建议加上去 毕竟也不差那10ms
*/

typedef void (*SystemClock_Config_Callback)(void);

typedef struct
{
	uint8_t SLEEPEntry;  //SLEEPEntry: 一般是 PWR_SLEEPENTRY_WFI 等待中断 也可以是 PWR_SLEEPENTRY_WFE
}LOW_POWER_SLEEPEntry_Cfg;

typedef struct
{
	uint8_t STOPEntry;  //STOPEntry: 一般是 PWR_STOPENTRY_WFI 等待中断 也可以是 PWR_STOPENTRY_WFE
}LOW_POWER_STOPEntry_Cfg;

typedef struct
{
	uint32_t WakeUpPinPolarity;  //WakeUpPinPolarity: 待机模式下WKUP唤醒引脚极性配置，其他模式无用 有的只能配置一个引脚 所以要看数据手册
	/*
	*    PWR_WAKEUP_PIN1_HIGH or PWR_WAKEUP_PIN1_LOW
  *    PWR_WAKEUP_PIN2_HIGH or PWR_WAKEUP_PIN2_LOW
  *    PWR_WAKEUP_PIN3_HIGH or PWR_WAKEUP_PIN3_LOW
  *    PWR_WAKEUP_PIN4_HIGH or PWR_WAKEUP_PIN4_LOW
  *    PWR_WAKEUP_PIN5_HIGH or PWR_WAKEUP_PIN5_LOW
	*/
}LOW_POWER_WakeUpPin_Cfg;

typedef struct
{
	bool EnableNotDisable;
	RTC_HandleTypeDef *rtc_handle;
	uint32_t counter;  //RTC计数值 由于进入低功耗模式会有约10ms消抖 所以建议减去这段时间
	uint32_t clock;  //RTC时钟源 一般是 RTC_WAKEUPCLOCK_RTCCLK_DIV16
}LOW_POWER_RTC_Cfg;

typedef struct
{
	bool EnableNotDisable;
	UART_HandleTypeDef *uart_handle;
	UART_WakeUpTypeDef UART_WakeUpStruct;  //UART唤醒的结构体配置 UART_WakeUpStruct.WakeUpEvent = UART_WAKEUP_ON_READDATA_NONEMPTY 就是接收数据不为空时唤醒
}LOW_POWER_UART_Cfg;

typedef struct
{
	LOW_POWER_UART_Cfg UART_Cfg[5];  //串口唤醒配置 有五个串口 所以最大buf长度为5
}LOW_POWER_Device_Cfg;

typedef struct
{
	uint8_t mode_flag;  // 0/大于4 不进入任何模式，1 进入睡眠，2 进入停止1，3 进入待机，4 关机
	
	LOW_POWER_SLEEPEntry_Cfg SLEEPEntry_Cfg;  //进入睡眠模式的方式
	LOW_POWER_STOPEntry_Cfg STOPEntry_Cfg;  //进入停止模式的方式
	LOW_POWER_WakeUpPin_Cfg WakeUpPin_Cfg ;   //待机模式的唤醒引脚配置
	
	LOW_POWER_RTC_Cfg RTC_Cfg;  //RTC唤醒配置
	LOW_POWER_Device_Cfg Device_Cfg;	
	
	SystemClock_Config_Callback SystemClock_Config_Fxn;	 // 用于传入退出相关低功耗模式后 需要进行配置的系统时钟配置函数
}LOW_POWER_Entry_Cfg;

extern LOW_POWER_Entry_Cfg LP_Entry_Cfg;

void GPIO_Reset_Init(bool EnableNotDisable);
void PWR_Device_Init(bool EnableNotDisable);
uint8_t Ctrl_UART_StopMode_WakeUp(LOW_POWER_UART_Cfg *UART_Cfg,bool EnableNotDisable);
void Ctrl_RTC_WakeUp(LOW_POWER_RTC_Cfg *RTC_Cfg,bool EnableNotDisable);

void Ctrl_Stop_Mode_WakeUp_Device(bool EnableNotDisable);
void Enter_Low_PWR(void);

void Init_Enter_Low_PWR(SystemClock_Config_Callback SystemClock_Config_Fxn);
	
#endif
